/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
    if (arguments.length === 0 || !time) {
      return null
    }
    const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
    let date
    if (typeof time === 'object') {
      date = time
    } else {
      if ((typeof time === 'string')) {
        if ((/^[0-9]+$/.test(time))) {
          time = parseInt(time)
        } else {
          time = time.replace(new RegExp(/-/gm), '/')
        }
      }

      if ((typeof time === 'number') && (time.toString().length === 10)) {
        time = time * 1000
      }
      date = new Date(time)
    }
    const formatObj = {
      y: date.getFullYear(),
      m: date.getMonth() + 1,
      d: date.getDate(),
      h: date.getHours(),
      i: date.getMinutes(),
      s: date.getSeconds(),
      a: date.getDay()
    }
    const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
      const value = formatObj[key]
      // Note: getDay() returns 0 on Sunday
      if (key === 'a') {
        return ['日', '一', '二', '三', '四', '五', '六'][value]
      }
      return value.toString().padStart(2, '0')
    })
    return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
    if (('' + time).length === 10) {
      time = parseInt(time) * 1000
    } else {
      time = +time
    }
    const d = new Date(time)
    const now = Date.now()

    const diff = (now - d) / 1000

    if (diff < 30) {
      return '刚刚'
    } else if (diff < 3600) {
      return Math.ceil(diff / 60) + '分钟前'
    } else if (diff < 3600 * 24) {
      return Math.ceil(diff / 3600) + '小时前'
    } else if (diff < 3600 * 24 * 2) {
      return '1天前'
    }
    if (option) {
      return parseTime(time, option)
    } else {
      return (
        d.getMonth() +
        1 +
        '月' +
        d.getDate() +
        '日' +
        d.getHours() +
        '时' +
        d.getMinutes() +
        '分'
      )
    }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
  if (!search) {
    return {}
  }
  const obj = {}
  const searchArr = search.split('&')
  searchArr.forEach(v => {
    const index = v.indexOf('=')
    if (index !== -1) {
      const name = v.substring(0, index)
      const val = v.substring(index + 1, v.length)
      obj[name] = val
    }
  })
  return obj
}

// 标准时间 转换
export function getApiTime(dataTime, format, timeStamp) {
  let formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];
  dataTime = dataTime || '';
  format = format || 'Y-M-D h:m:s';
  // 使用方式
  let returnArr = [];
  let date = '';
  // 根据传入的时间转换格式
  if (dataTime.toString().indexOf("-") == -1 && dataTime.toString().indexOf("/") == -1) {
    if (dataTime.toString().length > 10) {
      date = dataTime ? new Date(dataTime) : new Date();
    } else {
      date = dataTime ? new Date(dataTime * 1000) : new Date();
    }
  } else {
    date = dataTime ? new Date(dataTime.replace(/-/g, '/')) : new Date();
  }
  returnArr.push(date.getFullYear());
  returnArr.push(formatNumber(date.getMonth() + 1));
  returnArr.push(formatNumber(date.getDate()));
  returnArr.push(formatNumber(date.getHours()));
  returnArr.push(formatNumber(date.getMinutes()));
  returnArr.push(formatNumber(date.getSeconds()));
  for (let i in returnArr) {
    format = format.replace(formateArr[i], returnArr[i]);
  }
  return format;
}

function formatNumber(n) {
    n = n.toString()
    return n[1] ? n : '0' + n
}

// 北京时间戳
export function timeStamp(val) {
  return new Date(val).getTime() / 1000;
}

// 转化时间戳
export function easternTime(val) {
  let seconds = new Date().getTimezoneOffset() * 60, //本地时区与零时区差的秒数;
    serveSeconds = JSON.parse(localStorage.getItem('vuex')).user.userInfo.timeZoneSecond, //服务器与零时区差的秒数;
    difference = seconds - serveSeconds;
  if (val) {
    return parseInt(new Date(val).getTime() / 1000 - difference)
  } else {
    return parseInt(new Date().getTime() / 1000 - difference)
  }
}


/**
 * 函数节流
 * 触发事件立即执行，但在n秒内连续触发则不执行
 */
export function throttle(fn, wait = 1000) {
  let timer;
  return function () {
    if (timer != null) return;
    let context = this;
    let args = arguments;
    fn.apply(context, args);
    timer = setTimeout(() => {
      timer = null;
    }, wait);
  }
}


/**
 * 数据深拷贝
 */

export function deepCopy(obj, parent = null) {
    let result
    let _parent = parent
    while (_parent) {
      if (_parent.originalParent === obj) {
        return _parent.currentParent
      }
      _parent = _parent.parent
    }
    if (obj && typeof (obj) === 'object') {
      if (obj instanceof RegExp) {
        result = new RegExp(obj.source, obj.flags)
      } else if (obj instanceof Date) {
        result = new Date(obj.getTime())
      } else {
        if (obj instanceof Array) {
          result = []
        } else {
          let proto = Object.getPrototypeOf(obj)
          result = Object.create(proto)
        }
        for (let i in obj) {
          if (obj[i] && typeof (obj[i]) === 'object') {
            result[i] = deepCopy(obj[i], {
              originalParent: obj,
              currentParent: result,
              parent: parent
            })
          } else {
            result[i] = obj[i]
          }
        }
      }
    } else {
      return obj
    }
    return result
}

/**
 * @description: 计算本周内1-7周日23:59:59分的时间戳
 * @param dateStr: string: 2012-05-26 00:00:00
 * @returns timeStamp: Long int
 * @name getWeekLastStamp
 */
export function getWeekLastStamp(dateStr = parseTime(new Date().getTime())) {
  // 计算00:00:00时间的时间戳
  const timeStr = parseTime(dateStr, "{y}-{m}-{d}") + " 00:00:00";
  const zeroStamp = new Date(timeStr).getTime();
  const spanWeekDay = new Date(timeStr).getDay() ? (8 - new Date(timeStr).getDay()) : 1;
  const weekLastStamp = zeroStamp + spanWeekDay * 24 * 3600 * 1000 - 1000;
  console.log(parseTime(new Date(weekLastStamp)))
  return weekLastStamp;
}